use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};

use axum::{extract::FromRef, Router};
use carpet::server::{define_handler_straw, handler::MethodHandlerStraw, Server};
use log::info;
use tower_http::cors::CorsLayer;

#[derive(Debug, Default, FromRef, Clone)]
pub struct TemplateServer {
    pub db: String,
}

define_handler_straw!(TemplateServer);

impl Server for TemplateServer {
    type State = Self;

    type HandlerStraw = MethodHandlerStrawImpl;

    fn startup_message(&self, _addr: &SocketAddr) {
        info!("启动完成");
    }

    fn addr(&self) -> Result<SocketAddr, anyhow::Error> {
        Ok(std::net::SocketAddr::V4(SocketAddrV4::new(
            Ipv4Addr::from([0, 0, 0, 0]),
            9030,
        )))
    }

    fn state(&self) -> Self::State {
        self.clone()
    }

    fn routes(&self) -> Router<Self::State> {
        let mut routers: Router<Self::State> = Router::new();
        for m in inventory::iter::<Self::HandlerStraw> {
            let router_handler_fn = m.path_hander_fn();
            let item = router_handler_fn();
            routers = routers.route(&item.path, item.handler.fallback(Self::fallback405));
        }
        routers.layer(CorsLayer::permissive())
    }
}
